/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.marcelo.comun.database;

import java.util.List;

/**
 *
 * @author marcelo
 */
public class PaginadorImpl<T> implements IPaginador{
    
    private List<T> lista;
    private Integer pagina;
    private Integer porPagina;
    private static Integer PRIMER_ELEMENTO = 0;
    private static Integer CERO = 0;

   
    public PaginadorImpl(List<T> lista, Integer pagina, Integer porPagina) {
        this.lista = lista;
        this.pagina = pagina;
        this.porPagina = porPagina;
    }
    
    @Override
    public Integer pagina() {
        return pagina;
    }

    @Override
    public Boolean tieneSiguiente() {
        return numeroPaginas() != pagina;
    }

    @Override
    public void siguiente() {
        pagina++;
    }

    @Override
    public void anterior() {
        if (pagina > 1)
            pagina--;
    }
    
    private Integer desplazamiento(Integer offset){
        return ((offset - 1) * porPagina) ;
    }

    @Override
    public Integer desplazamiento() {
       return desplazamiento(pagina);
    }

    @Override
    public Integer limite() {
        return limite(pagina);
    }
    
    private Integer limite(Integer offset){
        Integer desplazamiento = desplazamiento(offset);
        Integer tamanhoPagina = this.porPagina;
        if ((desplazamiento + tamanhoPagina) > lista.size() ){
//            calcular los huerfanos;
            tamanhoPagina = lista.size() % tamanhoPagina;
            
        }
        return desplazamiento + tamanhoPagina ;
    }

    @Override
    public Boolean tieneAnterior() {
       return pagina > 1;
    }

    @Override
    public List<T>  inicio() {
        resetPagina();
        return getLista(PRIMER_ELEMENTO, porPagina);
    }

    @Override
    public List<T>  fin() {
        //calcular ultima pagina;
        //calcular huerfanos;
      pagina =  numeroPaginas();
      return getLista(desplazamiento(pagina), limite(pagina));
    }

    @Override
    public List<T> getPagina() {
       return getLista(desplazamiento(), limite());
    }

    private List<T> getLista(Integer from, Integer to){
        Integer totalSolicitado;
        if (to < from) {
            totalSolicitado = from - to;
        }
        else {
            totalSolicitado = to - from;
        }
        if (lista.size() < totalSolicitado) {
            return lista;
        }
        return lista.subList(from, to);
    }
    
    
    @Override
    public Integer numeroPaginas() {
       Integer totalPaginas = lista.size() / porPagina;
       Integer huerfanos = lista.size() % porPagina;
       if (huerfanos > CERO) {
           totalPaginas++;
       }
       return  totalPaginas;
    }

    @Override
    public void setLista(List newList) {
        this.lista = newList;
//        resetPagina(); 
    }

    @Override
    public void resetPagina() {
        pagina = 1;
    }

    @Override
    public Integer numeroElementos() {
        return this.lista.size();
    }
    
}
